package com.tzu.gateway.bean;

import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;
import com.tzu.gateway.bean.handler.ConnHandler;
import io.vertx.core.Vertx;
import io.vertx.core.net.NetServer;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import thirdpart.checksum.ICheckSum;
import thirdpart.codec.IBodyCodec;
import thirdpart.fetchsurv.IFetchService;

import java.io.File;
import java.io.InputStream;

/**
 * @Author: Tzu
 * @Date: 2020/11/15 14:28
 * @Version: 1.0
 * @Description:
 */

@Log4j2
@Getter
public class GatewayConfig {

    //网关
    private short id;

    //柜台通信端口
    private int recvport;

    //排队机通信端口
    private int fetchServPort;

    @Setter
    private IBodyCodec bodyCodec;

    @Setter
    private ICheckSum cs;

    private Vertx vertx = Vertx.vertx();

    ////////////////////网关启动接口////////////////////////////////////

    public void startup(){
        //1、上游：启动TCP服务监听 读取/缓存柜台发来的订单数据
        initRecv();
        //2、下游：排队机交互：准备订单数据 等待排队机拉取
        initFetchServ();
    }

    //////////////////////// TCP服务监听/////////////////////////////////////////////////

    /**
     * 1、监听网关是否成功启动
     * 2、读取并缓存柜台发来的订单数据
     */
    private void initRecv(){
        //创建vertx实例
        NetServer server = vertx.createNetServer();
        //绑定连接处理器：读取从柜台发来的订单数据并缓存到内存中
        server.connectHandler(new ConnHandler(this));
        //监听端口
        server.listen(recvport,res->{
            if (res.succeeded()){
                log.info("gateway startup success at port:{}",recvport);
            }else {
                log.info("gateway startup fail");
            }
        });
    }

    ///////////////////////////网关/排队机交互//////////////////////////////////////////////
    /**
     * 使用sofa的rpc框架进行通信
     */
    private void initFetchServ() {
        //1、设置要连接的排队机端口/协议
        ServerConfig rpcConfig = new ServerConfig()
                .setPort(fetchServPort)
                .setProtocol("bolt");

        //2、取出缓存队列的订单数据 并绑定rpcConfig
        ProviderConfig<IFetchService> providerConfig = new ProviderConfig<IFetchService>()
                .setInterfaceId(IFetchService.class.getName())
                .setRef(()->OrderCmdContainer.getInstance().getAll())
                .setServer(rpcConfig);

        //3、把数据放到指定接口，等待排队机拉取
        providerConfig.export();

        log.info("gateway startup fetchServ success at port : {}",fetchServPort);
    }



    /////////////////////////////读取指定配置文件的配置信息///////////////////////////////////

    public void initConfig(InputStream in) throws Exception{
        //创建dom4j解析器
        SAXReader saxReader = new SAXReader();
        //解析指定文件
        Document document = saxReader.read(in);
        //获取根标签
        Element root = document.getRootElement();

        //1、获取配置文件数据(id、recvport)
        id = Short.parseShort(root.element("id").getText());
        recvport = Integer.parseInt(root.element("recvport").getText());
        fetchServPort = Integer.parseInt(root.element("fetchservport").getText());

        log.info("GateWay ID:{}, Port:{}, FetchServPort:{}", id, recvport, fetchServPort);
        //TODO 数据库连接 连接柜台列表
    }
}
